// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// t [author] rhyme_lph
// F [email]  rhymelph@gmail.com
// w [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/bill_entity.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/form_utils.dart';
import 'package:finance_app/src/utils/permission_utils.dart';
import 'package:finance_app/src/utils/reg_exp_utils.dart';
import 'package:finance_app/src/utils/transaction_type_utils.dart';
import 'package:finance_app/src/widgets/button/add_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_white_button.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/input/search_input_field.dart';
import 'package:finance_app/src/widgets/select/bill_number_check_box.dart';
import 'package:finance_app/src/widgets/wrapper/normal_form_wrapper.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/provider/dashboard/bill/bill_number_provider.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:tuple/tuple.dart';

export 'package:finance_app/src/entities/bill_entity.dart';

@RouterMeta(paramName: "billNumberPage")
class BillNumberPage extends StatefulWidget {
  final bool isSingleSelect;
  final BillEntity select;
  final List<BillEntity> selects;
  final int filterIssueTo;
  final bool hideClosedBill;

  const BillNumberPage(
      {Key key,
      this.isSingleSelect,
      this.select,
      this.selects,
      this.filterIssueTo,
      this.hideClosedBill})
      : super(key: key);

  @override
  _BillNumberPageState createState() => _BillNumberPageState();
}

class _BillNumberPageState extends State<BillNumberPage>
    with PagePresenter<BillNumberPage, BillNumberProvider> {
  @override
  void initState() {
    provider.bills = widget.selects ?? [];
    provider.filterIssueTo = widget.filterIssueTo;
    provider.bill = widget.select;
    provider.bills = widget.selects ?? [];
    provider.isSingleSelect = widget.isSingleSelect ?? false;
    provider.hideClosedBill = widget.hideClosedBill ?? true;
    super.initState();
  }

  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(
        title: S.current.bill_number,
      );

  @override
  Widget get buildEmptyWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildTopWidget(),
                Expanded(
                  child: super.buildEmptyWidget,
                ),
              ],
            ),
            if (provider.isSingleSelect == false) _buildBottomBar()
          ],
        ),
      );

  @override
  Widget get buildWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildTopWidget(),
                Expanded(
                  child: listBuilder<String>(
                    selector: (_, __) => __.searchController.text,
                    builder:
                        (BuildContext context, String value, Widget child) {
                      List<Widget> childList = buildChildList(value);
                      return childList.isEmpty
                          ? super.buildEmptyWidget
                          : SmartRefresher(
                              controller: provider.refreshController,
                              onRefresh: provider.onRefresh,
                              onLoading: provider.onLoadMore,
                              enablePullUp: provider.hasUp,
                              child: ListView(
                                children: childList,
                              ),
                            );
                    },
                  ),
                ),
              ],
            ),
            if (provider.isSingleSelect == false) _buildBottomBar()
          ],
        ),
      );

  Widget _buildBottomBar() => Positioned(
      bottom: getDp(32) + MediaQuery.of(context).padding.bottom,
      left: 0.0,
      right: 0.0,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          NormalFloatTextWhiteButton(
            title: S.current.cancel,
            onTap: provider.onCancel,
          ),
          SizedBox(
            width: getDp(15),
          ),
          NormalFloatTextButton(
            title: S.current.done,
            onTap: provider.onDone,
          ),
        ],
      ));

  List<Widget> buildChildList(String value) {
    return provider.data.toList().map((e) => buildSliverItem(e)).toList();
  }

  Widget buildSliverItem(BillEntity data) {
    return listBuilder<Tuple2<BillEntity, bool>>(
      selector: (_, __) => Tuple2(
          data,
          __.isSingleSelect
              ? __.bill?.id == data.id
              : __.bills.firstWhere((element) => element.id == data.id,
                      orElse: () => null) !=
                  null),
      builder: (BuildContext context, Tuple2<BillEntity, bool> value,
              Widget child) =>
          PressedOpacityButton(
        onPressed: () => provider.onSelect(value.item1),
        child: widget.isSingleSelect == true
            ? BillNumberRadio(
                title: value.item1?.contact?.name ?? '',
                billNumber: value.item1.number,
                due: DateTimeUtils.formatDateTimeString(value.item1.dueAt),
                amount: value.item1.total.toDouble(),
                status:
                    value.item1.isOverdue == 1 && value.item1.status == 'open'
                        ? "Overdue"
                        : FormUtils.getStatus(
                            TransactionTypeUtils.getTransactionTypeStatus(
                                value.item1.dataType),
                            value.item1.status,
                            0),
                unit: value.item1.currencyCode,
                isSelect: value.item2,
              )
            : BillNumberCheckBox(
                title: value.item1?.contact?.name ?? '',
                billNumber: value.item1.number,
                due: DateTimeUtils.formatDateTimeString(value.item1.dueAt),
                amount: value.item1.total.toDouble(),
                status:
                    value.item1.isOverdue == 1 && value.item1.status == 'open'
                        ? "Overdue"
                        : FormUtils.getStatus(
                            TransactionTypeUtils.getTransactionTypeStatus(
                                value.item1.dataType),
                            value.item1.status,
                            0),
                unit: value.item1.currencyCode,
                isSelect: value.item2,
              ),
      ),
    );
  }

  bool _onSearchInputGroup(BillEntity element) {
    String searchInput = provider.searchController.text;
    return RegExpUtils.getSearchRegExp(searchInput)
        .hasMatch(element.contact.name);
  }

  Widget _buildTopWidget() {
    return Column(
      children: [
        AppSpaces.h20,
        SearchInputField(
          controller: provider.searchController,
          focusNode: provider.searchFocusNode,
        ),
        Config.hasPermission(PermissionUtils.bill)
            ? Column(
                children: [
                  NormalFormWrapper(
                    child: AddButton(
                      title: S.current.add_bill,
                      onTap: provider.onNavAddBill,
                    ),
                  ),
                  AppSpaces.grayH05,
                ],
              )
            : AppSpaces.h20,
      ],
    );
  }
}
